<?php
/**
 * SQL_Maker_Base
 *
 * PHP version 5
 *
 * LICENSE:
 *
 * Copyright (c) 2012, sink <sink.cup@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * The names of the authors may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @category sql maker
 * @package  SQL_Maker
 * @author   sink <sink.cup@gmail.com>
 * @license  http://opensource.org/licenses/bsd-license.php New BSD License
 * @version  SVN: $Id: Request2.php 324936 2012-04-07 07:49:03Z avb $
 * @link     http://pear.php.net/package/SQL_Maker/
 */

abstract class SQL_Maker_Base
{
    protected $char = array();
    protected $conf;
    protected $db;

    public function __construct($db_connection, array $conf = array())
    {
        if(!empty($conf)) {
            //can't use array_merge, because $this->conf may be empty
            foreach($conf as $k=>$v) {
                $this->conf[$k] = $v;
            }
        }
        $this->db = $db_connection;
    }

    abstract public function limit($limit_start, $limit_size);

    abstract protected function quote($data);

    abstract protected function quoteColumn($data);

    abstract public function quoteIdentifier($data);

    abstract public function quoteTableName();
    
    /**
     * column array to string, 用于select和insert
     *
     * @param mixed $data
     *
     * @return   string
     * @throws   SQL_Maker_Exception
     */
    public function implodeToColumn($data)
    {
        if(empty($data)) {
            throw new SQL_Maker_Exception();
        }
        if($data=='*') {
            return '*';
        }
        if(is_array($data)) {
            $tmp = array();
            foreach($data as $one) {
                $tmp[] = $this->quoteColumn($one);
            }
            $r = implode(',', $tmp); //eg. `id`,`name`,`desc`
        }
        else {
            $r = $this->quoteColumn($data); //eg. 'name'
        }
        return $r;
    }

    public function implodeToRowValues($data)
    {
        if(is_array($data)) {
            $tmp = array();
            foreach($data as $one) {
                $tmp[] = $this->quote($one);
            }
            $a = implode(',', $tmp);
        }
        else {
            $a = $this->quote($data);
        }
        $b = '(' . $a . ')';
        return $b;
    }

    /**
     * input: array(
     *  array(1, 'jim'),
     *  array(2, 'lucy'),
     * )
     * output: ('1','jim'),('2','lucy')
     * @param array $data
     * @return string
     */
    public function implodeToRowsValues($data) {
        foreach($data as $value) {
            $tmp = $this->implodeToRowValues($value);
            $row_array[] = $tmp;
        }
        $rows = implode(',',$row_array);
        return $rows;
    }

    /**
     * input: array(
     *      'id' => array(
     *          1,2,3
     *      ),
     *      'year' => '2012'
     * )
     * output: WHERE `id` IN ('1','2','3') AND `year`='2012'
     * @param array $data
     * @return string
     */
    public function implodeToWhere($data)
    {
        if(!is_array($data) || empty($data)) {
            return '';
        }
        $r = '';
        $map = array(
            'e' => '=',
            'lt' => '<',
            'lte' => '<=',
            'gt' => '>',
            'gte' => '>=',
        );
        foreach($map as $str=>$math) {
            if(!isset($data[$str]) || empty($data[$str])) {
                continue;
            }
            foreach($data[$str] as $key=>$value) {
                if(is_array($value)) {
                    $tmp = array();
                    foreach($value as $one) {
                        $tmp[] = $this->quote($one);
                    }
                    $part_1 =  $this->quoteIdentifier($key) . ' IN (' . implode(',', $tmp) . ') ';
                } else {
                    $part_1 = $this->quoteIdentifier($key) . $math . $this->quote($value);
                }
                if(!empty($r)) {
                    $r .= ' AND ';
                }
                $r .= $part_1;
            }
        }
        if(empty($r)) {
            return '';
        } else {
            return ' WHERE ' . $r;
        }
    }

    /**
     * input: array(
     *      'name' => 'jim',
     *      'year' => '2012'
     * )
     * output: `name`='jim',`year`='2012'
     * @param array $data
     * @return string
     */
    public function implodeToUpdate($data) {
        if(empty($data)) {
            throw new SQL_Maker_Excption();
        }
        $r = '';
        /*if(isset($data['add'])) {
            foreach($data['add'] as $column=>$value) {
                if(!empty($r)) {
                    $r .= ',';
                }
                $r .= $this->quoteIdentifier($column) . '=' . $this->quoteIdentifier($column) . '+' . $this->quote($value);
            }
        }
        unset($data['add']);*/
        foreach($data as $column=>$value) {
            if(!empty($r)) {
                $r .= ',';
            }
            $r .= $this->quoteIdentifier($column) . '=' . $this->quote($value);
        }
        return $r;
    }
}
?>
